package com.bluetrum.abmate.dialog;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;

import com.bluetrum.abmate.bluetooth.adapter.DevicesAdapter;
import com.bluetrum.abmate.databinding.LayoutInfoNoBluetoothBinding;
import com.bluetrum.abmate.databinding.LayoutInfoNoBluetoothPermissionsBinding;
import com.bluetrum.abmate.databinding.LayoutInfoNoDevicesBinding;
import com.bluetrum.abmate.databinding.LayoutInfoNoLocationPermissionBinding;
import com.bluetrum.abmate.databinding.LayoutScannerBottomSheetBinding;
import com.bluetrum.abmate.utils.Utils;
import com.bluetrum.abmate.viewmodels.ScannerStateLiveData;
import com.bluetrum.abmate.viewmodels.ScannerViewModel;
import com.bluetrum.devicemanager.models.ABDevice;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.android.material.button.MaterialButton;

import static android.app.Activity.RESULT_OK;

import dagger.hilt.android.AndroidEntryPoint;
import timber.log.Timber;

@AndroidEntryPoint
public class BottomSheetScannerDialogFragment extends BottomSheetDialogFragment
        implements DevicesAdapter.OnItemClickListener {

    private LayoutScannerBottomSheetBinding binding;
    private LayoutInfoNoDevicesBinding layoutInfoNoDevicesBinding;
    private LayoutInfoNoBluetoothBinding layoutInfoNoBluetoothBinding;
    private LayoutInfoNoLocationPermissionBinding layoutInfoNoLocationPermissionBinding;
    private LayoutInfoNoBluetoothPermissionsBinding layoutInfoNoBluetoothPermissionsBinding;

    private ScannerViewModel mViewModel;

    public interface BottomSheetScannerListener {
        void selectedDevice(ABDevice device);
    }

    private ActivityResultLauncher<Intent> enableBluetoothLauncher;
    private ActivityResultLauncher<String> locationPermissionLauncher;
    private ActivityResultLauncher<String[]> bluetoothPermissionLauncher;

    public static BottomSheetScannerDialogFragment getInstance() {
        return new BottomSheetScannerDialogFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mViewModel = new ViewModelProvider(this).get(ScannerViewModel.class);
        binding = LayoutScannerBottomSheetBinding.inflate(inflater, container, false);
        layoutInfoNoDevicesBinding = binding.noDevices;
        layoutInfoNoBluetoothBinding = binding.bluetoothOff;
        layoutInfoNoLocationPermissionBinding = binding.noLocationPermission;
        layoutInfoNoBluetoothPermissionsBinding = binding.noBluetoothPermissions;

        layoutInfoNoDevicesBinding.buttonEnableLocation.setOnClickListener(this::clickEnableLocation);
        layoutInfoNoBluetoothBinding.buttonEnableBluetooth.setOnClickListener(this::clickEnableBluetooth);
        layoutInfoNoLocationPermissionBinding.buttonGrantLocationPermission.setOnClickListener(this::clickGrantLocationPermission);
        layoutInfoNoLocationPermissionBinding.buttonPermissionSettings.setOnClickListener(this::clickPermissionSettings);
        layoutInfoNoBluetoothPermissionsBinding.actionGrantBluetoothPermission.setOnClickListener(this::clickGrantBluetoothPermissions);
        layoutInfoNoBluetoothPermissionsBinding.actionPermissionSettings.setOnClickListener(this::clickPermissionSettings);

        enableBluetoothLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        startScan(mViewModel.getScannerRepository().getScannerState());
                    }
                }
        );
        locationPermissionLauncher = registerForActivityResult(
                new ActivityResultContracts.RequestPermission(),
                result -> mViewModel.getScannerRepository().getScannerState().startScanning()
        );
        bluetoothPermissionLauncher = registerForActivityResult(
                new ActivityResultContracts.RequestMultiplePermissions(),
                result -> mViewModel.getScannerRepository().getScannerState().startScanning()
        );

        setupListView();
        return binding.getRoot();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    private void setupListView() {
        RecyclerView recyclerViewDevices = binding.recyclerView;

        recyclerViewDevices.setLayoutManager(new LinearLayoutManager(requireActivity()));
        final DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerViewDevices.getContext(), DividerItemDecoration.VERTICAL);
        recyclerViewDevices.addItemDecoration(dividerItemDecoration);

        final SimpleItemAnimator itemAnimator = (SimpleItemAnimator) recyclerViewDevices.getItemAnimator();
        if (itemAnimator != null) itemAnimator.setSupportsChangeAnimations(false);

        final DevicesAdapter adapter = new DevicesAdapter(requireActivity(), mViewModel.getScannerRepository().getScannerResults());
        adapter.setOnItemClickListener(this);
        recyclerViewDevices.setAdapter(adapter);

        mViewModel.getScannerRepository().getScannerState().observe(this, this::startScan);
    }

    @Override
    public void onStart() {
        super.onStart();
        mViewModel.getScannerRepository().getScannerState().startScanning();
    }

    @Override
    public void onStop() {
        super.onStop();
        stopScan();
    }

    private void clickEnableLocation(View view) {
        final Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivity(intent);
    }

    private void clickEnableBluetooth(View view) {
        final Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        enableBluetoothLauncher.launch(intent);
    }

    private void clickGrantLocationPermission(View view) {
        Utils.markLocationPermissionRequested(requireActivity());
        locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION);
    }

    private void clickGrantBluetoothPermissions(View view) {
        if (Utils.isAndroid12OrAbove()) {
            Utils.markBluetoothPermissionsRequested(requireActivity());
            bluetoothPermissionLauncher.launch(new String[]{Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT});
        }
    }

    private void clickPermissionSettings(View view) {
        final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", requireActivity().getPackageName(), null));
        startActivity(intent);
    }

    @Override
    public void onItemClick(ABDevice device) {
        stopScan();
        if (getActivity() != null) {
            ((BottomSheetScannerListener) getActivity()).selectedDevice(device);
        } else if (getParentFragment() != null) {
            ((BottomSheetScannerListener) getParentFragment()).selectedDevice(device);
        }
        Timber.e("====点击设备:%s", device.getBleName()+","+device.getBleAddress());
        dismiss();
    }

    /**
     * Start scanning for Bluetooth devices or displays a message based on the scanner state.
     */
    private void startScan(final ScannerStateLiveData state) {
        View noLocationPermissionView = layoutInfoNoLocationPermissionBinding.getRoot();
        View noBluetoothPermissionsView = layoutInfoNoBluetoothPermissionsBinding.getRoot();
        View noBluetoothView = layoutInfoNoBluetoothBinding.getRoot();
        View noDevicesView = layoutInfoNoDevicesBinding.getRoot();
        View noLocationView = layoutInfoNoDevicesBinding.noLocation;
        ProgressBar progressBar = binding.progressBar;
        MaterialButton grantLocationPermissionButton = layoutInfoNoLocationPermissionBinding.buttonGrantLocationPermission;
        MaterialButton permissionSettingsButton = layoutInfoNoLocationPermissionBinding.buttonPermissionSettings;
        MaterialButton grantBluetoothPermissionsButton = layoutInfoNoBluetoothPermissionsBinding.actionGrantBluetoothPermission;
        MaterialButton bluetoothPermissionsSettingsButton = layoutInfoNoBluetoothPermissionsBinding.actionPermissionSettings;

        if (Utils.isBluetoothScanAndConnectPermissionsGranted(requireActivity())) {
            noBluetoothPermissionsView.setVisibility(View.GONE);
            // First, check the Location permission. This is required on Marshmallow onwards in order to scan for Bluetooth LE devices.
            if (Utils.isLocationPermissionsGranted(requireActivity())) {
                noLocationPermissionView.setVisibility(View.GONE);

                // Bluetooth must be enabled
                if (state.isBluetoothEnabled()) {
                    noBluetoothView.setVisibility(View.GONE);

                    if (!state.isScanning()) {
                        // We are now OK to start scanning
                        mViewModel.getScannerRepository().startScan();
                        progressBar.setVisibility(View.VISIBLE);
                    }

                    if (state.isEmpty()) {
                        noDevicesView.setVisibility(View.VISIBLE);

                        if (!Utils.isLocationRequired(requireActivity()) || Utils.isLocationEnabled(requireActivity())) {
                            noLocationView.setVisibility(View.INVISIBLE);
                        } else {
                            noLocationView.setVisibility(View.VISIBLE);
                        }
                    } else {
                        noDevicesView.setVisibility(View.GONE);
                    }
                } else {
                    noBluetoothView.setVisibility(View.VISIBLE);
                    progressBar.setVisibility(View.INVISIBLE);
                    noDevicesView.setVisibility(View.GONE);
                }
            } else {
                noLocationPermissionView.setVisibility(View.VISIBLE);
                noBluetoothView.setVisibility(View.GONE);
                progressBar.setVisibility(View.INVISIBLE);
                noDevicesView.setVisibility(View.GONE);

                final boolean deniedForever = Utils.isLocationPermissionDeniedForever(requireActivity());
                grantLocationPermissionButton.setVisibility(deniedForever ? View.GONE : View.VISIBLE);
                permissionSettingsButton.setVisibility(deniedForever ? View.VISIBLE : View.GONE);
            }
        } else {
            noBluetoothPermissionsView.setVisibility(View.VISIBLE);
            noBluetoothView.setVisibility(View.GONE);
            progressBar.setVisibility(View.INVISIBLE);
            noDevicesView.setVisibility(View.GONE);

            if (Utils.isAndroid12OrAbove()) {
                final boolean deniedForever = Utils.isBluetoothPermissionDeniedForever(requireActivity());
                grantBluetoothPermissionsButton.setVisibility(deniedForever ? View.GONE : View.VISIBLE);
                bluetoothPermissionsSettingsButton.setVisibility(deniedForever ? View.VISIBLE : View.GONE);
            }
        }
    }

    /**
     * stop scanning for bluetooth devices.
     */
    private void stopScan() {
        mViewModel.getScannerRepository().stopScan();
    }

}
